package com.idol.framework.factory;

import com.idol.framework.annotation.AutoWired;
import com.idol.framework.annotation.Controller;
import com.idol.framework.annotation.Service;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Supreme_Sir
 * @version 1.0
 * @className BeanFactory
 * @description 用以实例化 Bean，并将实例化后的 Bean 放入 IoC 容器中
 * @date 2020/10/31 15:20
 **/
public class BeanFactory {
    private static BeanFactory instance = new BeanFactory();
    private BeanContainer beanContainer = BeanContainer.getInstance();

    /**
     * 实例化所有被扫描到的 Bean 至 IoC 容器
     * @param classPathList
     */
    public void doCreateBeans(List<String> classPathList) {
        if (classPathList.size() > 0) {
            try {
                for (String className : classPathList) {
                    Class<?> aClass = Class.forName(className);
                    if (aClass.isAnnotationPresent(Controller.class)) {
                        String simpleName = aClass.getSimpleName();
                        beanContainer.put(lowerFirstChar(simpleName), aClass.newInstance());
                    } else if (aClass.isAnnotationPresent(Service.class)) {
                        Service service = aClass.getAnnotation(Service.class);
                        String serviceName = service.value();
                        if ("".equals(serviceName.trim())) {
                            serviceName = lowerFirstChar(aClass.getSimpleName());
                        }
                        Object instance = aClass.newInstance();
                        beanContainer.put(serviceName, instance);

                        // 通常情况情况下 Server 层都有实现接口，所以这里也设置通过接口名获取实例化对象
                        Class<?>[] interfaces = aClass.getInterfaces();
                        for (Class<?> aInterface : interfaces) {
                            beanContainer.put(aInterface.getSimpleName(), instance);
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    /**
     * 对带有 @AutoWired 注解的属性进行注入
     */
    public void doAutoWired() {
        Set<Map.Entry<String, Object>> entrySet = beanContainer.getEntrySet();
        if (entrySet.isEmpty()) {
            return;
        }
        for (Map.Entry<String, Object> entry : entrySet) {
            Field[] declaredFields = entry.getValue().getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                if (!field.isAnnotationPresent(AutoWired.class)) {
                    continue;
                }

                AutoWired autoWired = field.getAnnotation(AutoWired.class);
                String beanName = autoWired.value();
                if ("".equals(beanName.trim())) {
                    beanName = field.getType().getSimpleName();
                }

                field.setAccessible(true);
                try {
                    field.set(entry.getValue(), beanContainer.get(beanName));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
    }



    /**
     * 首字母小写
     * @param str
     * @return
     */
    private String lowerFirstChar(String str) {
        str = str.trim();
        if (str.length() > 0){
            char[] chars = str.toCharArray();
            if ('A' <= chars[0] && 'Z' >= chars[0]) {
                chars[0] += 32;
            }
            return String.valueOf(chars);
        }
        return str;
    }

    public static BeanFactory getInstance() {
        return instance;
    }

    private BeanFactory() {
    }
}
